using System;
using System.Collections.Generic;
using System.Text;
using Interop = Microsoft.Feeds.Interop;
using System.Windows.Threading;
using System.Collections;

namespace Ricciolo.PaperBoy.Feeds
{
    public class FeedsManager
    {

        internal readonly Interop.IFeedsManager feedsManager;
        private FeedFolder _rootFolder;
        internal readonly Dispatcher dispatcher;
        internal readonly Hashtable allfeeds = new Hashtable();

        public event EventHandler<NewFeedItemsEventArgs> NewFeedItems;
        private static readonly FeedsManager _feedsManager = new FeedsManager();

        private FeedsManager()
        {
            this.feedsManager = new Interop.FeedsManagerClass();
            this.dispatcher = Dispatcher.CurrentDispatcher;
        }

        /// <summary>
        /// Get a feed/folder by path
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public FeedBase GetFeedByPathFromCache(string path)
        {
            WeakReference wr = this.allfeeds[path] as WeakReference;
            if (wr != null && wr.IsAlive)
                return wr.Target as FeedBase;
            return null;
        }

        /// <summary>
        /// Get a feed/folder by uri.
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        public Feed GetFeedByUri(string uri)
        {
            Interop.IFeed ifeed = this.feedsManager.GetFeedByUrl(uri) as Interop.IFeed;
            Feed feed = null;
            if (ifeed != null)
            {
                feed = this.GetFeedByPathFromCache(ifeed.Path) as Feed;
                if (feed == null)
                    feed = new Feed(this, ifeed.Path);
            }
            return feed;
        }

        public static FeedsManager Current
        {
            get { return _feedsManager;}
        }

        public void SyncronizeAll()
        {
            this.feedsManager.AsyncSyncAll();
        }

        /// <summary>
        /// Retrieves the root subscription folder
        /// </summary>
        public FeedFolder RootFolder
        {
            get
            {
                if (_rootFolder == null)
                    _rootFolder = new FeedFolder(this, ((Interop.IFeedFolder)this.feedsManager.RootFolder).Path);

                return _rootFolder;
            }
        }

        /// <summary>
        /// Retrieves the system-defined limit of items retained for feeds.
        /// </summary>
        public int ItemCountLimit
        {
            get { return this.feedsManager.ItemCountLimit; }
        }

        /// <summary>
        /// Sets or retrieves the default update interval for feeds.
        /// </summary>
        public int DefaultInterval
        {
            get { return this.feedsManager.DefaultInterval; }
            set { this.feedsManager.DefaultInterval = value; }
        }

        internal void OnNewFeedItems(NewFeedItemsEventArgs e)
        {
            if (NewFeedItems != null)
                NewFeedItems(this, e);
        }
    }

    public class NewFeedItemsEventArgs : EventArgs
    {
        private Feed _feed;
        private IList<FeedItem> _newItems;

        public NewFeedItemsEventArgs(Feed feed, IList<FeedItem> newItems)
        {
            _feed = feed;
            _newItems = newItems;
        }

        public Feed Feed
        {
            get { return _feed; }
        }

        public IList<FeedItem> NewItems
        {
            get { return _newItems; }
        }
    }
}
